const _ = require('lodash');
// lodash 的 curry 方法
const newAdd = _.curry(function(n1, n2, n3) {
  return n1 + n2 + n3;
});

// console.log(newAdd(1, 2, 3));
// console.log(newAdd(1)(2, 3));
// console.log(newAdd(1, 2)(3));
// console.log(newAdd(1)(2)(3));

// 可以看到，上面的 console 打印，将函数 颗粒化 了，那么，实现一下
/**
 * 首先整理一下思路
 * 1、第七行代码，如果一次性传入足够的参数，那么会返回函数的返回值
 * 2、8，9，10 行代码分多次传入参数，但是事实上如果参数没有传完，会返回一个函数，并不会返回函数返回值
 * 
 * 1、判断形参与实参数量是否一致
 * 
 * 扩展
 * 如何知道函数的形参有多少呢？
 * your_function.length
 */

function selfCurry(fun) {
  return function notAllArgsFun(...args) {// 可以通过 ES6 的方法，一次性接收全部参数
    if (args.length < fun.length) {
      // 如果当前传入参数小于形参，返回一个函数，继续传
      return function() {
        // 这里有一个误区，要注意下，这个 arguments 是 33 行代码的 arguments，刚刚没想明白这个 arguments 是为什么
        return notAllArgsFun(...args.concat(Array.from(arguments)));
      }
    }
    // 参数全部传完了，可以返回函数运行结果了
    return fun(...args);
  }
}

const selfAdd = selfCurry(function(n1, n2, n3) {
  return n1 + n2 + n3;
});

// console.log(selfAdd(1, 2, 3));
// console.log(selfAdd(1)(2, 3));
// console.log(selfAdd(1, 2)(3));
// console.log(selfAdd(1)(2)(3));
